home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.unix
- From: creps@silver.ucs.indiana.edu (Steve Creps)
- Subject: v25i073: newmail - utility to check for new mail
- Sender: sources-moderator@pa.dec.com
- Approved: vixie@pa.dec.com
-
- Submitted-By: creps@silver.ucs.indiana.edu (Steve Creps)
- Posting-Number: Volume 25, Issue 73
- Archive-Name: newmail
-
- This is a program I wrote a couple of years ago to check for
- new mail. I originally wrote it so that I could type a quick
- command to check my mail without actually going into mail, but
- recently added an option to let it run in the background.
-
- This was first written on a VAX running Ultrix, but most of the
- recent changes were done under HP-UX. I did, however, try it out
- and lint it again under Ultrix. Send me any bug reports. I hope
- this will be the last version, but if not, I hope it's the next-to-
- last version, the last being a bugfix.
-
- Steve Creps
- creps@silver.ucs.indiana.edu (129.79.1.6)
- {inuxc,rutgers,uunet!uiucdcs,pur-ee}!iuvax!silver!creps
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 1)."
- # Contents: BSD.man Makefile README SYSV.man killnewmail.BSD
- # killnewmail.SYSV newmail.c newmail.man
- # Wrapped by creps@silver on Fri Jul 19 18:52:20 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'BSD.man' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'BSD.man'\"
- else
- echo shar: Extracting \"'BSD.man'\" \(29 characters\)
- sed "s/^X//" >'BSD.man' <<'END_OF_FILE'
- X.ds MB /usr/spool/mail/$USER
- END_OF_FILE
- if test 29 -ne `wc -c <'BSD.man'`; then
- echo shar: \"'BSD.man'\" unpacked with wrong size!
- fi
- # end of 'BSD.man'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(954 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X# Makefile for newmail(1), Steve Creps, July 17, 1991.
- X#LOC=/usr/contrib
- XLOC=/usr2/creps
- XBIN=$(LOC)/bin
- XMAN=$(LOC)/man/man1.Z
- X#
- X# Define for BSD, Ultrix, etc.
- XSYSTEM=BSD
- X# Define for SYS V, HP-UX, etc.
- X#SYSTEM=SYSV
- X#
- XOWNER=creps
- XCFLAGS=-O -s -D$(SYSTEM)
- XLINTFLAGS=-D$(SYSTEM)
- XKILLFILES=killnewmail.SYSV killnewmail.BSD
- XMANFILES=newmail.man BSD.man SYSV.man
- XFILES=newmail.c $(MANFILES) $(KILLFILES) README Makefile
- X
- Xnewmail: newmail.c
- X cc $(CFLAGS) -o newmail newmail.c
- X
- Xnewmail.1: newmail.man $(SYSTEM).man
- X cat $(SYSTEM).man newmail.man >newmail.1
- X
- Xkillnewmail: killnewmail.$(SYSTEM)
- X cp killnewmail.$(SYSTEM) killnewmail
- X
- Xinstall: newmail newmail.1 killnewmail
- X chmod 0555 newmail killnewmail
- X chmod 0444 newmail.1
- X chown $(OWNER) newmail newmail.1 killnewmail
- X mv newmail killnewmail $(BIN)
- X compress newmail.1
- X mv newmail.1.Z $(MAN)/newmail.1
- X
- Xtar: newmail.tar
- X
- Xnewmail.tar: $(FILES)
- X tar cvf newmail.tar $(FILES)
- X
- Xlint:
- X lint $(LINTFLAGS) newmail.c
- END_OF_FILE
- if test 954 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(495 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- XNewmail, version 3.0, Steve Creps, July 19, 1991.
- XGive information on existence of new mail messages. See the man
- Xpage file (newmail.man) for information on the program.
- X
- XThis program has been tested under Ultrix and HP-UX.
- X
- XPrevious versions had no version numbers, only dates, so 3.0 is
- Xa somewhat arbitrary version number.
- X
- XChanges from previous version to version 3.0:
- X
- X- Rewrote command line parsing code to use getopt(3).
- X
- X- Added -i option and killnewmail script (daemon mode handling).
- END_OF_FILE
- if test 495 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'SYSV.man' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'SYSV.man'\"
- else
- echo shar: Extracting \"'SYSV.man'\" \(26 characters\)
- sed "s/^X//" >'SYSV.man' <<'END_OF_FILE'
- X.ds MB /usr/mail/$LOGNAME
- END_OF_FILE
- if test 26 -ne `wc -c <'SYSV.man'`; then
- echo shar: \"'SYSV.man'\" unpacked with wrong size!
- fi
- # end of 'SYSV.man'
- fi
- if test -f 'killnewmail.BSD' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'killnewmail.BSD'\"
- else
- echo shar: Extracting \"'killnewmail.BSD'\" \(92 characters\)
- sed "s/^X//" >'killnewmail.BSD' <<'END_OF_FILE'
- X#!/bin/sh
- Xkill `ps -fg | fgrep newmail | fgrep -e -d | fgrep -v fgrep | awk '{ print $1 }'`
- END_OF_FILE
- if test 92 -ne `wc -c <'killnewmail.BSD'`; then
- echo shar: \"'killnewmail.BSD'\" unpacked with wrong size!
- fi
- # end of 'killnewmail.BSD'
- fi
- if test -f 'killnewmail.SYSV' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'killnewmail.SYSV'\"
- else
- echo shar: Extracting \"'killnewmail.SYSV'\" \(101 characters\)
- sed "s/^X//" >'killnewmail.SYSV' <<'END_OF_FILE'
- X#!/bin/sh
- Xkill `ps -fu $LOGNAME | fgrep newmail | fgrep -e -d | fgrep -v fgrep | awk '{ print $2 }'`
- END_OF_FILE
- if test 101 -ne `wc -c <'killnewmail.SYSV'`; then
- echo shar: \"'killnewmail.SYSV'\" unpacked with wrong size!
- fi
- # end of 'killnewmail.SYSV'
- fi
- if test -f 'newmail.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'newmail.c'\"
- else
- echo shar: Extracting \"'newmail.c'\" \(5561 characters\)
- sed "s/^X//" >'newmail.c' <<'END_OF_FILE'
- X/* newmail(1L), check for new, unread, and total mail messages */
- X/* Steve Creps, October 24, 1988 */
- X/* Last modified, July 19, 1991 */
- X
- X/****************************************************************/
- X/* #include standard copyright notice: */
- X/* This program copyright Steve Creps on the above date. Do */
- X/* pretty much what you want with it; HOWEVER: */
- X/* 1) Don't accept any money for it. */
- X/* 2) Do leave my notices intact. */
- X/* 3) Do document your changes before passing it on. */
- X/****************************************************************/
- X
- X#ifndef lint
- Xstatic char ID[] = "Newmail, version 3.0, (c) 1991 Steve Creps";
- X#endif
- X
- X#include <stdio.h>
- X#include <string.h>
- X#include <errno.h>
- X#include <sys/types.h>
- X#include <malloc.h>
- X
- X#define Fprintf (void)fprintf
- X#define Printf (void)printf
- X#define NEW 1
- X#define UNREAD 2
- X#define OLD 3
- X#define DEF_INTERVAL 30 /* Default sleep time between checks */
- X#define MIN_INTERVAL 5 /* Min must be > 0 */
- X#ifdef BSD
- X#define MAILDIR "/usr/spool/mail"
- X#define ENV_USER "USER"
- X#else
- X#define MAILDIR "/usr/mail"
- X#define ENV_USER "LOGNAME"
- X#endif
- X
- Xint optn = 0, optt = 0, optv = 1, opti = 0, optd = 0;
- Xint optb = 0;
- Xint ncount, ucount, tcount, old_ncount = -1;
- Xint nextmsg(), type;
- X
- Xchar *getenv(), *getln();
- Xint getopt();
- Xunsigned int sleep();
- Xvoid exit();
- Xextern int opterr, optind;
- Xextern char *optarg;
- Xpid_t fork(), getpid();
- X
- Xint
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X char *mailfile;
- X int c;
- X FILE *mailfp;
- X pid_t child_id = 0;
- X
- X opterr = 0;
- X while ((c = getopt(argc, argv, "bdi:nstv")) != EOF) {
- X switch (c) {
- X case 'b':
- X optb = 1;
- X break;
- X
- X case 'd':
- X optd = optn = 1;
- X opti = DEF_INTERVAL;
- X break;
- X
- X case 'i':
- X if ((opti = atoi(optarg)) < MIN_INTERVAL) {
- X Fprintf(stderr,
- X "newmail: time interval is too small\n");
- X exit(-1);
- X }
- X break;
- X
- X case 'n':
- X optn = 1;
- X optt = 0;
- X break;
- X
- X case 's':
- X optt = optv = 0;
- X break;
- X
- X case 't':
- X optt = 1;
- X optn = optv = 0;
- X break;
- X
- X case 'v':
- X optv = 1;
- X optt = 0;
- X break;
- X
- X case '?':
- X Fprintf(stderr, "newmail: invalid option: %s\n",
- X argv[optind - 1]);
- X exit(-1);
- X }
- X }
- X
- X if (argc > optind + 1) {
- X Fprintf(stderr, "Usage: newmail [ -b -d -i interval -n -s -t -v ] [ mailbox ]\n");
- X exit(-1);
- X }
- X
- X if (optd == 0 || (child_id = fork()) == 0) {
- X if (optd && child_id == 0) {
- X Printf("newmail daemon started, pid == %d\n", getpid());
- X }
- X
- X if (argc == optind) {
- X char *u = getenv(ENV_USER);
- X mailfile = (char *)malloc(sizeof(MAILDIR) + sizeof("/") +
- X sizeof(u) + 1);
- X (void)sprintf(mailfile, "%s/%s", MAILDIR, u);
- X } else {
- X#ifdef SYSV
- X mailfile = strdup(argv[optind]);
- X#else
- X /* No strdup() on Ultrix; sigh. Don't try to free this below. */
- X mailfile = argv[optind];
- X#endif
- X }
- X
- X do {
- X ncount = ucount = tcount = 0;
- X if ((mailfp = fopen(mailfile, "r")) == NULL) {
- X if (errno != ENOENT || argc > optind) {
- X Fprintf(stderr, "newmail: cannot open %s\n",
- X mailfile);
- X return -1;
- X }
- X } else {
- X while (type = nextmsg(mailfp)) {
- X switch (type) {
- X case NEW:
- X ncount++;
- X
- X case UNREAD:
- X ucount++;
- X
- X case OLD:
- X tcount++;
- X break;
- X
- X default:
- X continue;
- X }
- X }
- X }
- X
- X if (ncount > old_ncount) {
- X if (optv) {
- X if (optb && ncount > 0) putchar(0x07);
- X if (tcount == 0) {
- X if (!optn) Printf("%s: no messages.\n",
- X mailfile);
- X } else {
- X Printf("%s: ", mailfile);
- X if (ncount) Printf("%d new, ", ncount);
- X if (ucount && ucount != ncount)
- X Printf("%d unread, ", ucount);
- X Printf("%d message%s total.\n", tcount,
- X tcount > 1 ? "s" : "");
- X }
- X } else if (optt)
- X Printf("%d\t%d\t%d\n", ncount, ucount, tcount);
- X }
- X old_ncount = ncount;
- X (void)fclose(mailfp);
- X#ifdef BSD
- X if (opti > 0) (void)sleep((unsigned)opti);
- X#else
- X if (opti > 0) (void)sleep((unsigned long)opti);
- X#endif
- X } while (opti > 0);
- X }
- X#ifdef SYSV
- X /* Just to be neat. See comment after strdup() above. */
- X free((void *)mailfile);
- X#endif
- X
- X return optd > 0 ? child_id : ncount;
- X}
- X
- X#define MAXLEN 12 /* we're discarding most of the end of the line */
- Xstatic char line[MAXLEN] = NULL;
- X
- Xint
- Xnextmsg(fp)
- XFILE *fp;
- X{
- X int mtype = NEW, past_header = 0;
- X while (strncmp(line, "From ", 5) != 0)
- X if (getln(fp, line, MAXLEN) == NULL) return 0;
- X do {
- X if (strlen(line) == 1) {
- X past_header++;
- X while (strlen(line) == 1)
- X (void)getln(fp, line, MAXLEN);
- X if (strncmp(line, "From ", 5) == 0) {
- X return mtype;
- X }
- X }
- X if (strncmp(line, "Status: O", 9) == 0) {
- X if (!past_header) mtype = UNREAD;
- X continue;
- X }
- X if (strncmp(line, "Status: RO", 10) == 0) {
- X if (!past_header) mtype = OLD;
- X continue;
- X }
- X } while (getln(fp, line, MAXLEN));
- X
- X return mtype;
- X}
- X
- X/* Read a line from given stream, return in line. If line is too */
- X/* long, truncate and read past next \n. Terminate with (char)0. */
- Xchar *
- Xgetln(fp, msgline, maxlen)
- XFILE *fp;
- Xchar msgline[];
- Xint maxlen;
- X{
- X int i, maxc = maxlen - 2;
- X char c;
- X for (i = 0; i < maxc && (msgline[i] = getc(fp)) != '\n'; i++) {
- X if ((int)msgline[i] == EOF) {
- X msgline[0] = (char)0;
- X return NULL;
- X }
- X }
- X
- X if (i == maxc) {
- X msgline[maxc++] = '\n';
- X msgline[maxc] = (char)0;
- X while ((c = getc(fp)) != '\n') {
- X if ((int)c == EOF) {
- X msgline[0] = (char)0;
- X return NULL;
- X }
- X }
- X } else {
- X msgline[i++] = '\n';
- X msgline[i] = (char)0;
- X }
- X
- X return msgline;
- X}
- END_OF_FILE
- if test 5561 -ne `wc -c <'newmail.c'`; then
- echo shar: \"'newmail.c'\" unpacked with wrong size!
- fi
- # end of 'newmail.c'
- fi
- if test -f 'newmail.man' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'newmail.man'\"
- else
- echo shar: Extracting \"'newmail.man'\" \(2552 characters\)
- sed "s/^X//" >'newmail.man' <<'END_OF_FILE'
- X.TH NEWMAIL 1L
- X.SH NAME
- Xnewmail \- display numbers of new, unread, and total mail messages
- X.SH SYNTAX
- X.B newmail
- X[ \fB-b -d -i interval -n -s -t -v\fR ] [ \fBmailbox\fR ]
- X
- X.B killnewmail
- X
- X.SH DESCRIPTION
- XThe
- X.I newmail
- Xcommand displays the number of messages in the given \fBmailbox\fR,
- Xbroken down by new messages, unread messages, and total (including
- Xold) messages.
- XIt also returns as a status code the number of new messages in the
- Xmailbox.
- XIf \fBmailbox\fR is not specified, then it checks the user's default
- Xmailbox,
- X\*(MB.
- X
- X.I Killnewmail
- Xis a shell script that kills the
- X.I newmail
- Xdaemon (see the -d option).
- X
- X.I Newmail
- Xaccepts the following flags:
- X
- X.IP \fB\-b\fP 5
- XBeep if the mailbox contains new messages.
- X
- X.IP \fB\-d\fP 5
- XThis option starts
- X.I newmail
- Xas a daemon which checks the mailbox every
- X.B interval
- Xseconds.
- XIf
- X.B interval
- Xis not specified, it defaults to 30 seconds.
- X
- X.IP \fB\-i interval\fP 5
- XSpecifies a time interval for a delay between repeated mailbox
- Xchecks.
- XThis puts the program into an endless loop.
- XIf this option is desired, consider also the \fB-d\fR option.
- X
- X.IP \fB\-n\fP 5
- XInhibits an output message if \fBmailbox\fR contains no messages.
- X
- X.IP \fB\-s\fP 5
- XSpecifies silent mode.
- XNothing is displayed, but the return status gives the number of
- Xmessages.
- XOptions \fB-s\fR, \fB-t\fR, and \fB-v\fR are mutually exclusive, and
- Xoverride one another.
- X
- X.IP \fB\-t\fP 5
- XSpecifies terse mode.
- XThe numbers of messages are displayed in the form "new unread total",
- Xsuitable for piping through \fIawk\fR.
- X
- X.IP \fB\-v\fP 5
- XSpecifies verbose mode.
- XDisplays the numbers of messages in \fBmailbox\fR in the format
- X"\*(MB: x new, y unread, z total messages".\
- XIf x or y is zero, then the corresponding output field will be
- Xomitted.
- XDefault.
- X.PP
- X
- X.SH DIAGNOSTICS
- XA nonnegative return code specifies the number of new messages in
- X\fBmailbox\fR.
- XIf the \fB-d\fR option is specified, then the pid of the created
- Xdaemon is returned.
- XA return code of -1 indicates an error.
- X
- X.SH CAVEAT
- XWhen in a looping mode (\fB-i\fR or \fB-d\fR), \fInewmail\fR can miss
- Xmessages that arrive within \fBinterval\fR seconds of reading one's
- Xmail (and thus clearing the messages' "new" flags).
- XThis is because \fInewmail\fR is interested only in net increases in
- Xthe mailbox message count, and it takes that much time before the
- Xcount can be assumed to be reset to zero.
- X
- X.SH AUTHOR
- XWritten by Steve Creps, Indiana University, October 24, 1988, based
- Xon observation of Unix mailbox format.
- XNot derived from anyone else's code.
- XLast modified July 19, 1991.
- END_OF_FILE
- if test 2552 -ne `wc -c <'newmail.man'`; then
- echo shar: \"'newmail.man'\" unpacked with wrong size!
- fi
- # end of 'newmail.man'
- fi
- echo shar: End of archive 1 \(of 1\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have the archive.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
-